package com.liu.frame.http;


import android.content.Context;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.liu.frame.application.MyApplication;
import com.liu.frame.base.Basebean;
import com.liu.frame.beans.UserBean;
import com.liu.frame.config.Api;
import com.liu.frame.customview.PullTorefreshView;
import com.liu.frame.utils.GsonUtils;
import com.liu.frame.utils.LoadingUtil;
import com.liu.frame.utils.LogUtils;
import com.liu.frame.utils.NetWorkUtil;
import com.liu.frame.utils.SharedPreferencesUtils;
import com.liu.frame.utils.ToastUtils;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.List;

import retrofit2.http.POST;
import retrofit2.http.QueryMap;
import rx.Observable;
import rx.Observer;
import rx.Producer;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created by 刘智强 on 2017/2/13.
 * 发起网络请求
 */

public class WeiLiCaiNetWorks<T > extends WeiLiCaiRetrofit {
    //设缓存有效期为1天
    protected static final long CACHE_STALE_SEC = 60 * 60 * 24 * 1;
    //查询缓存的Cache-Control设置，使用缓存
    protected static final String CACHE_CONTROL_CACHE = "only-if-cached, max-stale=" + CACHE_STALE_SEC;
    //查询网络的Cache-Control设置。不使用缓存
    protected static final String CACHE_CONTROL_NETWORK = "max-age=0";

    private static String code;//接口返回的状态码
    private static String message;//接口返回的信息
    private static String returnInfo;//接口返回的JSON数据
    private Class<T> entityClass;//泛型的类型
    private Context context;

    @SuppressWarnings("unchecked")
    public WeiLiCaiNetWorks(Context context) {
        entityClass = this.getSuperClass();
        this.context = context;
    }

    /**
     * 发起网络请求
     *
     * @param observable
     * @param callBack
     */

    public Subscription post(Observable observable, final CallBack callBack) {
        Subscription subscription = null;
        /**
         * 没有网络读取缓存
         */
        if (!NetWorkUtil.isNetwork(MyApplication.getInstance())) {
            ToastUtils.myToast(MyApplication.getInstance(), "暂无网络");

        } else {

            subscription = observable.subscribeOn(Schedulers.io())
                    .unsubscribeOn(Schedulers.io())
                    .subscribeOn(Schedulers.newThread())//子线程访问网络
                    .observeOn(AndroidSchedulers.mainThread())//回调到主线程
                    .subscribe(new Subscriber<String>() {
                        @Override
                        public void onCompleted() {
                            callBack.completed();
                            LoadingUtil.getInstance().dismissDialog();
                        }

                        @Override
                        public void onError(Throwable e) {
                            callBack.error();
                            if (e.getCause() instanceof SocketTimeoutException) {
                                ToastUtils.myToast(context, "链接超时");
                            }else  if (e.getCause() instanceof ConnectException){
                                ToastUtils.myToast(context, "链接异常");

                            }
                            e.printStackTrace();

                            LoadingUtil.getInstance().dismissDialog();
                        }

                        @Override
                        public void onNext(String response) {
                            returnInfo = GsonUtils.json2String(response, "returnInfo");
                            code = GsonUtils.json2String(response, "returnCode");
                            message = GsonUtils.json2String(response, "returnMessage");
                            LogUtils.e(returnInfo);
                            LogUtils.e(code);
                            LogUtils.e(message);
                            switch (code) {
                                case "00000":
                                    //成功
                                    try {
                                        LogUtils.e(entityClass.getName());
                                        if (returnInfo.startsWith("{")) {
                                            //实体
                                            T data = GsonUtils.fromJson(returnInfo, entityClass);
                                            callBack.success(code, message, data);
                                        } else if (returnInfo.startsWith("[")) {
                                            //List<实体>
                                            List<T> data = GsonUtils.fromJsonArray(returnInfo, entityClass);
                                            callBack.success(code, message, data);
                                        }
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                        ToastUtils.myToast(context, "数据解析出现问题了");
                                    }
                                    break;
                                case "00001":
                                    ToastUtils.myToast(context,message);
                                    new SharedPreferencesUtils(context).remove(Api.LOGIN);
                                    callBack.fail(code, message, returnInfo);
                                    break;
                                default:

                                    callBack.fail(code, message, returnInfo);
                            }
                        }

                        @Override
                        public void onStart() {
                            super.onStart();
                            callBack.start();
                            LoadingUtil.getInstance().showDialog(context, "");
                        }

                        @Override
                        public void setProducer(Producer p) {
                            super.setProducer(p);
                        }
                    });
        }

        return subscription;
    }


    public interface CallBack<T> {
        /**
         * 请求开始
         */
        void start();

        /**
         * 请求完成
         */

        void completed();

        /**
         * 请求出错（主要指网络异常）
         */

        void error();

        /**
         * 请示失败（主要指业务失败 ）
         *
         * @param code
         * @param message
         * @param returnInfo
         */

        void fail(String code, String message, String returnInfo);


        /**
         * 请求成功(主要指业务成功)
         */

        void success(String code, String message, T t);


    }

    /**
     * 获取泛型类型
     *
     * @return
     */
    private Class getSuperClass() {
        return getSuperClassGenricType(getClass(), 0);
    }

    /**
     * 通过反射, 获得定义Class时声明的父类的泛型参数的类型. 如无法找到, 返回Object.class.
     *
     * @param clazz
     * @param index
     * @return
     */
    private Class<Object> getSuperClassGenricType(final Class clazz, final int index) {

        //返回表示此 Class 所表示的实体（类、接口、基本类型或 void）的直接超类的 Type。
        Type genType = clazz.getGenericSuperclass();
        if (!(genType instanceof ParameterizedType)) {
            return Object.class;
        }
        //返回表示此类型实际类型参数的 Type 对象的数组。
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        if (index >= params.length || index < 0) {
            return Object.class;
        }
        if (!(params[index] instanceof Class)) {
            return Object.class;
        }

        return (Class) params[index];
    }


}
